import getMessageLenght from "./helper";
import { DataSegment, SegmentItem } from "../datastructure/DataSegment"
import { DataProcessor } from "../datastructure/DataProcessor"
import { WebSocketClient } from "./websocketclient"
import { JSEncrypt } from 'jsencrypt'
import * as TOOL from '../UI/tool'

export class IM {
    public url: string;
    constructor(url: string) {
        this.url = url;
        this.messageProcesser = new MessageProcesser();
        this.ws = null;
    }

    // 进行握手 同步 返回是否成功
    public async handShake(room: string): Promise<any> {
        this.ws = new WebSocketClient();
        await this.ws.connect(this.url);
        let shandShakeData = new DataSegment();
        shandShakeData.put("user", window.localStorage.getItem("name") as string);
        shandShakeData.put("step", "1");
        await this._send(shandShakeData);

        // 步骤1 结束

        let step2 = await this.receive();
        if (step2.get("code") == "1") {
            return new Promise(r => r(step2));
        }
        let random = step2.get("random");
        let crypt = new JSEncrypt({ default_key_size: 2048 });
        let encrypt = new JSEncrypt({ default_key_size: 2048 });
        encrypt.setPublicKey(TOOL.setverPublicKey);
        crypt.setPublicKey(window.localStorage.getItem("publicKey"));
        crypt.setPrivateKey(window.localStorage.getItem("privateKey"));
        let decryptRandom = crypt.decrypt(random);
        let encryptRandom = encrypt.encrypt(decryptRandom);
        shandShakeData = new DataSegment();
        shandShakeData.put("room", room);
        shandShakeData.put("random", encryptRandom);
        shandShakeData.put("step", "2");
        await this._send(shandShakeData);

        // 步骤2 结束
        let step3 = await this.receive();
        return new Promise(r => r(step3));
    }

    // 发送聊天类型的消息
    public async sendChatMessage(message: string) {
        let dataSegment = new DataSegment();
        message = message == "" ? "null" : message;
        dataSegment.put("data", message);
        dataSegment.put("type", "chat");
        await this._send(dataSegment);
    }

    // 发送指令
    public async sendCommand(command: string) {
        let dataSegment = new DataSegment();
        command = command == "" ? "null" : command;
        dataSegment.put("data", command);
        dataSegment.put("type", "instruct");
        await this._send(dataSegment);
    }

    // 发送同步控制
    public async sendOnline(serial: string) {
        let dataSegment = new DataSegment();
        dataSegment.put("serial", serial);
        dataSegment.put("type", "online");
        dataSegment.put("what", "history")
        await this._send(dataSegment);
    }

    //发送请求状态栏
    public async sendStatus(status: string) {
        let dataSegment = new DataSegment();
        status = status == "" ? "null" : status;
        dataSegment.put("data", status);
        dataSegment.put("type", "status");
        await this._send(dataSegment);
    }

    //map
    public async sendMap(map: string, what: string) {
        let dataSegment = new DataSegment();
        map = map == "" ? "null" : map;
        dataSegment.put("data", map);
        dataSegment.put("what", what);
        dataSegment.put("type", "camera");
        await this._send(dataSegment);
    }

    // 接收指令 同步
    public async receive(): Promise<DataSegment> {
        let data = await this.ws!.receive();
        this.messageProcesser.push(data);
        if (this.messageProcesser.available) {
            let ans = this.messageProcesser.getMessage();
            this.messageProcesser.reset();
            return new Promise<DataSegment>(rs => rs(ans));
        } else {
            return await this.receive();
        }
    }
    public async work(): Promise<any> {
        return this.receive().then((message) => {
            console.log("收到", message)
            let type = message.get("type");
            switch (type) {
                case "chat":
                    this.onChat(message);
                    break;
                case "instruct":
                    this.onInstruct(message);
                    break;
                case "online":
                    this.onOnline(message);
                    break;
                case "camera":
                    this.onMap(message);
                    break;
                case "status":
                    this.onStatus(message);
                    break;
            }
        });
    }
    // 返回聊天信息
    public onChat = (e: DataSegment) => { };
    public onInstruct = (e: DataSegment) => { };
    public onOnline = (e: DataSegment) => { };
    public onMap = (e: DataSegment) => { };
    public onStatus = (e: DataSegment) => { };

    private async _send(messgae: DataSegment) {
        let toSend = this.messageProcesser.prepareMessage(messgae);
        console.log("发送", toSend);
        await this.ws!.send(toSend);
    }

    private ws: WebSocketClient | null;
    private messageProcesser: MessageProcesser;
}

export class MessageProcesser {
    constructor() {
        this.buffer = "";
        this.length = 0;
        this.available = false;
    }
    public push(string: string) {
        this.buffer += string;
        // 1.还没拿到长度 2.已经有长度
        if (getMessageLenght(this.buffer) != 0) {
            this.length = getMessageLenght(this.buffer);
            let bufferArry = this.buffer.split("#");
            bufferArry.shift();
            this.buffer = bufferArry.join("#");
        }
        if (this.length == this.buffer.length) {
            this.available = true;
        }
    }
    public reset() {
        this.buffer = "";
        this.length = 0;
        this.available = false;
    }
    public prepareMessage(message: DataSegment): string {
        let ans = DataProcessor.buildString(message);
        return ans.length.toString() + "#" + ans;
    }
    public getMessage(): DataSegment {
        return DataProcessor.buildSegment(this.buffer.toString());
    }
    public buffer: string;
    public length: number;
    public available: boolean;

}
